셸 정렬
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
셸 정렬은 삽입 정렬을 개선한 정렬 알고리즘으로, 멀리 떨어진 요소들을 교환하여 정렬 속도를 향상시킨다. 임의의 간격(h)을 두고 h-정렬된 상태를 만들며, 간격을 줄여가며 최종적으로는 h=1이 되어 전체 배열을 정렬한다. 셸 정렬의 성능은 간격 결정 방법에 따라 달라지며, 다양한 간격 수열이 제안되었지만, 아직 최적의 간격 수열은 밝혀지지 않았다. 시간 복잡도는 간격 수열에 따라 다르며, 최악의 경우 O(n^2)에서 O(n log^2 n)까지 다양하다. 셸 정렬은 퀵 정렬보다 구현이 간단하고 호출 스택을 사용하지 않아 임베디드 시스템이나 qsort 함수 구현에 활용되며, 내성 정렬의 하위 알고리즘으로도 사용된다.
셸 정렬은 삽입 정렬을 개선한 알고리즘으로, 삽입 정렬이 인접한 요소끼리만 비교, 교환하는 것과 달리 '간격(gap)'을 두고 멀리 떨어진 요소들을 비교, 교환한다. 이 간격을 점차 줄여나가면서 정렬을 반복 수행한다.[5]
2. 알고리즘
간단히 설명하면, 1024개의 숫자가 있을 때 첫 간격(''h'')을 512로 설정하고, 첫 번째 절반의 각 요소를 두 번째 절반의 요소와 비교한다. 두 번째 간격(''k'')은 256으로 배열을 4개의 섹션(0, 256, 512, 768)으로 나누고 각 섹션의 첫 번째 항목이 서로 상대적으로 정렬되어 있는지 확인한 다음, 각 섹션의 두 번째 항목 등을 확인하는 방식이다. 간격은 다양하게 설정할 수 있지만, 마지막 간격은 항상 1로 하여 정렬을 완료한다.[5]
간격이 5, 3, 1인 셸 정렬의 예시는 다음과 같다.
5-정렬은 5개의 하위 배열에 삽입 정렬을 수행하고, 3-정렬은 3개의 하위 배열, 1-정렬은 전체 배열에 대해 삽입 정렬을 수행한다.
셸 정렬은 안정적인 정렬이 아니며, 입력이 부분적으로 정렬될 때 더 빠르게 실행되는 적응형 정렬 알고리즘이다.
```c
# 배열 a[0...n-1]을 정렬한다.
gaps = [701, 301, 132, 57, 23, 10, 4, 1] # 치우라 간격 수열
# 가장 큰 간격에서 시작하여 간격이 1이 될 때까지 줄여나간다.
# 삽입 정렬과 유사하지만 각 단계에서 1 대신 간격을 사용한다.
foreach (gap in gaps)
{
# 간격 정렬을 모든 간격의 요소에 대해 수행한다.
# 각 루프는 a[0..gap-1]을 간격 정렬된 순서로 둔다.
for (i = gap; i < n; i += 1)
{
# a[i]를 temp에 저장하고 i 위치에 구멍을 만든다.
temp = a[i]
# a[i]의 올바른 위치를 찾을 때까지 이전의 간격 정렬된 요소를 위로 이동시킨다.
for (j = i; (j >= gap) && (a[j - gap] > temp); j -= gap)
{
a[j] = a[j - gap]
}
# temp (원래 a[i])를 올바른 위치에 넣는다.
a[j] = temp
}
}
2. 1. 동작 방식
셸 정렬은 삽입 정렬을 최적화한 알고리즘이다. 삽입 정렬의 경우, 각 요소는 한 번에 한 칸씩 이동한다. 하지만 셸 정렬은 멀리 떨어진 요소들을 먼저 교환하여 정렬 속도를 높인다.[5]
동작 방식:1. 간격(h) 설정: 정렬할 리스트에서 일정 간격(h)을 정한다. 이 간격은 처음에는 크고 점차 줄어든다.
2. h-정렬: 각 간격(h)에 대해, h번째 요소들끼리 비교하여 정렬한다. 즉, 리스트를 h개의 부분 리스트로 나누어 각 부분 리스트를 삽입 정렬로 정렬한다. 이를 'h-정렬'이라고 한다.[5]
3. 간격 감소 및 반복: 간격(h)을 줄여가면서 h-정렬을 반복한다. 간격이 1이 될 때까지, 즉 리스트 전체가 하나의 부분 리스트가 될 때까지 반복한다.[5]
4. 최종 정렬: 간격이 1이 되면, 사실상 일반적인 삽입 정렬을 수행하는 것과 같다. 하지만 이전 단계에서 이미 대부분 정렬이 이루어졌기 때문에 훨씬 빠르게 완료된다.[6]
예시:1024개의 숫자로 구성된 배열을 셸 정렬로 정렬하는 과정을 생각해보자.
간격(h) 값은 다양하게 설정할 수 있지만, 마지막 간격은 반드시 1이어야 한다.[5]
간격이 5, 3, 1인 경우의 셸 정렬 예시:
- 5-정렬: 5개의 부분 배열에 대해 삽입 정렬을 수행한다.
- 3-정렬: 3개의 부분 배열에 대해 삽입 정렬을 수행한다.
- 1-정렬: 전체 배열에 대해 삽입 정렬을 수행한다.
셸 정렬은 갭(간격)을 이용한 삽입 정렬을 수행하기 때문에, 동일한 요소의 순서가 바뀔 수 있어 안정적인 정렬은 아니다. 하지만 입력 데이터가 부분적으로 정렬되어 있을 때 더 빠르게 동작하는 적응형 정렬 알고리즘이다.
간격을 2의 거듭제곱으로 하는 예시:초기 데이터:
1. h=4: 같은 색으로 표시된 그룹끼리 삽입 정렬을 수행한다.